Repository navigation
fix: guard formatNumber against non-numeric values - #1721
Conversation
When table columns contain non-numeric values (strings, etc.) and a number format like Percent is applied, the formatting produces NaN because `numbro()` can't parse strings. The existing falsy check (`!value && value !== 0`) doesn't catch non-empty strings since they're truthy. Adds a `typeof` and `isNaN` guard to return the raw value as-is when it's not actually numeric. Fixes #1510
🦋 Changeset detectedLatest commit: 5a572ca The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@themavik is attempting to deploy a commit to the HyperDX Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@themavik I think we should only guard for isNaN - as it is possible for ClickHouse to return number values encoded as string due to https://clickhouse.com/docs/operations/settings/formats#output_format_json_quote_64bit_integers |
karl-power
left a comment
There was a problem hiding this comment.
IMO this change doesn't address the root cause of the attached issue.
The problem is that grouping columns can exist which aren't found in the groupByKeys array here. The number formatter is then applied to these columns and we see NaN.
That can happen by adding a group by like ServiceName as SN or ResourceAttributes['host.id'] and the resulting column name (SN and arrayElement(ResourceAttributes, 'host.id') respectively) is not found in the groupByKeys array.
A solution would be to extend the code that creates the groupByKeys to check if aliases are used, and add the alias only to the array.
- Remove typeof check; ClickHouse returns numbers as strings - Only guard for isNaN to catch truly non-numeric values Co-authored-by: Cursor <cursoragent@cursor.com>
|
Thanks for the feedback. I've narrowed the guard to only check @karl-power — good point about |
Code Review
The fix logic itself ( |
|
@themavik Can you cover the isNaN check with a test case in |
Code Review
✅ The fix logic itself is correct and aligns with @MikeShi42's feedback — numeric strings from ClickHouse ( |
Code Review
✅ The core fix logic is correct — numeric strings from ClickHouse ( |
## Summary Fixes #1510 **Root cause:** When a number format (e.g., Percent) is applied to table columns that contain non-numeric values, `formatNumber` doesn't catch non-empty strings. `numbro()` then produces NaN. The existing check `!value && value !== 0` catches `null`, `undefined`, and `NaN`, but NOT non-empty strings (which are truthy and pass through to `numbro()`). ## Changes - `packages/app/src/utils.ts`: Added `typeof value !== 'number' || isNaN(value)` guard that returns the raw value as a string instead of formatting it. ## Risk Assessment **Low** - Only adds a guard for an edge case. Numeric values are formatted exactly as before. Co-authored-by: Karl Power <85935352+karl-power@users.noreply.github.com>
Summary
Fixes #1510
Root cause: When a number format (e.g., Percent) is applied to table columns that contain non-numeric values,
formatNumberdoesn't catch non-empty strings.numbro()then produces NaN.The existing check
!value && value !== 0catchesnull,undefined, andNaN, but NOT non-empty strings (which are truthy and pass through tonumbro()).Changes
packages/app/src/utils.ts: Addedtypeof value !== 'number' || isNaN(value)guard that returns the raw value as a string instead of formatting it.Risk Assessment
Low - Only adds a guard for an edge case. Numeric values are formatted exactly as before.